// overlay.js

var Appalachian = {};

Appalachian._pageWatcher = null;
Appalachian._observer = null;
Appalachian._state = new AppalachianFSM();

Appalachian.load = function() {
    AppalachianDB.init();
    Appalachian.getState().init();
    AppalachianPrefs.init();
    var show = AppalachianPrefs.getPref(SHOW_STATUS_PREF_KEY);
    if (show) document.getElementById("appalachian-status-icon").style.display = 'block';
    Appalachian._pageWatcher = new AppalachianPageWatcher(appalachianNormalLocationChange)
    HeaderCache.init();
    gBrowser.addProgressListener(Appalachian._pageWatcher, Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
};

Appalachian.unload = function() {
    gBrowser.removeProgressListener(Appalachian._pageWatcher);
    HeaderCache.destroy();
    Appalachian._pageWatcher = null;
};

Appalachian.getState = function() {
    return Appalachian._state;
};

window.addEventListener("load", Appalachian.load, false);
window.addEventListener("unload", Appalachian.unload, false);

Appalachian.verify = function(url) {
    var stringBundle = document.getElementById("appalachian-bundle");
    var openid = AppalachianDB.getInfo(Appalachian.getState().getUsedOpenID());
    if (openid.compareServer(url)) {
        Appalachian.getState().advance(APPALACHIAN_ACTION_VERIFY);
    } else {
        Appalachian.getState().advance(APPALACHIAN_ACTION_WARN);
        var notifyBox = gBrowser.getNotificationBox(gBrowser.selectedBrowser);
        // Also, notifications aren't being removed and are triggering an exception - should probably make notifyBox null to kill link, too
        var b = function() {
            notifyBox.removeAllNotifications(true);
            if (AppalachianDB.useExists(Appalachian.getState().getUsedOpenID(), Appalachian.getState().getRequestor())) {
                var useid = AppalachianDB.getUseId(Appalachian.getState().getUsedOpenID(), Appalachian.getState().getRequestor());
                AppalachianDB.deleteUse(useid);
            }
            try {
                // go back two history entries
                var historyLength = gBrowser.selectedBrowser.sessionHistory.count;
                gBrowser.selectedBrowser.gotoIndex(historyLength - 3);
            } catch (e) {
                try {
                    gBrowser.selectedBrowser.goBack();
                } catch (ee) {
                    content.document.location.href = 'http://simile.mit.edu/wiki/Appalachian_Anti-Phishing';
                }
            }
            // do NOT advance the state here; there's already one
            // for page location changes
        };
        var c = function() {
            notifyBox.removeAllNotifications(true);
            content.document.body.style.opacity="1.0";
            Appalachian.getState().advance(APPALACHIAN_ACTION_STAY);
        };
        var f = function() {
            notifyBox.appendNotification(stringBundle.getString("phishWarning"), "", "chrome://appalachian/skin/warning-status.png", notifyBox.PRIORITY_CRITICAL_LOW, [{label: stringBundle.getString("leaveLabel"), accessKey: stringBundle.getString("leaveAccessKey"), callback: b}, {label: stringBundle.getString("ignoreLabel"), accessKey: stringBundle.getString("ignoreAccessKey"), callback: c}]);
        };
        var fade = function() {
            content.document.body.style.opacity="0.3";
        };
        setTimeout(f, 50);
        setTimeout(fade, 1500);
    }
}

Appalachian.checkSuccess = function() {
    // listen for mode
    // openid.mode=checkid_immediate: - record on receipt of redirect url
    //  openid.identity=: - read on... response...
    //      record success
    //  openid.user_setup_url=: - read on... response...
    //      can't say
    // openid.mode=checkid_setup: - record on receipt of redirect url
    //  openid.mode=id_res: - read on... response...
    //      record success
    //  openid.mode=cancel || content.document.location.href != openid.return_to: - read on... response...
    //      failed
}

appalachianNormalLocationChange = function(prog, req, uri) {
    return 0;
};

var AppalachianPageWatcher = function(locationChange) {
    this.onProgressChange = function() {return 0;}
    this.onStatusChange = function() {return 0;},
    this.onSecurityChange = function() {return 0;},
    this.onLinkIconAvailable = function() {return 0;},
    this.onLocationChange = locationChange;
}

const STATE_IS_DOCUMENT = Components.interfaces.nsIWebProgressListener.STATE_IS_DOCUMENT;
const STATE_START = Components.interfaces.nsIWebProgressListener.STATE_START;
const STATE_STOP = Components.interfaces.nsIWebProgressListener.STATE_STOP;

AppalachianPageWatcher.prototype.onStateChange = function(prog, req, flags, status) {
    AppalachianDebug.trace("overlay.js", Appalachian.getState().getCurrentState());
    if (APPALACHIAN_STATES[Appalachian.getState().getCurrentState()] != APPALACHIAN_STATE_LOGIN) {
        if (flags & (STATE_IS_DOCUMENT|STATE_START)) {
            Appalachian.getState().advance(APPALACHIAN_ACTION_LEAVE);
            if (req && req.URI && AppalachianDB.anyUseExists(req.URI.asciiSpec)) {
                Appalachian.getState().advance(APPALACHIAN_ACTION_DETECT_URL);
            }
        } else if (flags & (STATE_IS_DOCUMENT|STATE_STOP)) {
            var ls = prog.DOMWindow.document.getElementsByTagName('link');
            var matched = false;
            for (var i = 0; i < ls.length; i++) {
                if (ls[i].hasAttribute("rel") && ls[i].getAttribute("rel").indexOf("openid.server") != -1) {
                    if(!AppalachianDB.exists(prog.DOMWindow.document.location.href)) {
                        Appalachian.getState().advance(APPALACHIAN_ACTION_DETECT_DOM);
                        matched = true;
                        break;
                    }
                }
            }
            if (!matched) {
                var ylib = new Yadis(prog.DOMWindow.document.location.href);
                var f = function(isYadis) {
                    if (isYadis)
                        Appalachian.getState().advance(APPALACHIAN_ACTION_DETECT_YADIS);
                };
                ylib.discover(f, prog.DOMWindow.document);
                ylib = null;
            }
        }
    }
    return 0;
};

AppalachianPageWatcher.prototype.QueryInterface = function(aIID) {
    if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
        aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
        aIID.equals(Components.interfaces.nsISupports))
            return this;

    throw Components.results.NS_NOINTERFACE;
};
